/**
 * 请求实体数据、创建实体
 */
import * as DT from 'dt-sdk'
import moment from 'moment'
import { mapGetters } from 'vuex'
import { lodLayer } from '@/components/dt-scene/index.vue'
import { getRealOrbitList } from '@/api/scene'
import { BEAM_TYPE } from '@/enum'
import { debounce } from '@/utils'
import EntityControl from '@/mixin/entity-control.js'

export default {
  mixins: [EntityControl],
  data() {
    return {
      shouldWatch: true,
      nextQuery: { // 下一次轨迹数据请求时间
        preTime: '',
        nextTime: '',
        isQeury: false,
      },
      satelliteConfig: [], // 卫星配置信息
    }
  },
  computed: {
    ...mapGetters(['currentTime', 'speed', 'sceneMode']),
  },
  watch: {
    /**
     * 监听场景当前时间，更新地球上渲染物体的数据
     * @author Farley
     * @date 2021-11-24
     * @param {any} time
     * @returns {any}
     */
    currentTime(time) {
      let currentTime = DT.Cesium.JulianDate.fromIso8601(time)
      if (this.nextQuery.nextTime && this.shouldWatch) {
        let nextQueryTime = DT.Cesium.JulianDate.fromIso8601(this.nextQuery.nextTime)
        let preTime = DT.Cesium.JulianDate.fromIso8601(this.nextQuery.preTime)
        // 监听场景当前时间小于下一次请求时间时，并且下一次请求时间与当前时间差 小于 （速度 * 10）秒，发送请求下一时段数据
        if ((DT.Cesium.JulianDate.lessThan(currentTime, nextQueryTime) && (DT.Cesium.JulianDate.secondsDifference(nextQueryTime, currentTime) < 10 * this.speed))) {
          if (!this.nextQuery.isQeury) {
            if (this.nextQuery.preTime !== this.nextQuery.nextTime) {
              this.nextQuery.isQeury = true
              // 请求时间
              let queryTime = moment(this.nextQuery.nextTime).subtract(300, 'seconds').utc().format('YYYY-MM-DDTHH:mm:ss') + 'Z'
              this.nextQuery.preTime = this.nextQuery.nextTime
              this.getMap({ sceneId: this.sceneId, checkedIds: this.visibleIds, startTime: queryTime, step: 60 * 1 })
            }
          }
        }
        // （如果当前时间小于preTime 或者大于nextQueryTime）并且 当前时间与上一次请求时间差 大于 （速度 * 10） 秒 则需要更新数据
        if (DT.Cesium.JulianDate.greaterThan(currentTime, nextQueryTime) || (DT.Cesium.JulianDate.lessThan(currentTime, preTime) && (DT.Cesium.JulianDate.secondsDifference(preTime, currentTime) > 10 * this.speed))) {
          if (!this.nextQuery.isQeury) {
            this.nextQuery.isQeury = true
            // 请求时间
            this.nextQuery.preTime = time
            this.getMap({ sceneId: this.sceneId, checkedIds: this.visibleIds, startTime: time, step: 60 * 1 })
          }
        }
      }
    },
    // 监听场景变化， 实时和回放需要重新请求数据
    sceneMode: {
      handler: function (nv, ov) {
        if (this.shouldWatch) {
          lodLayer.removeAll()

          // if (nv) {
          //   // 回放模式
          //   this.getMap({ sceneId: this.sceneId, checkedIds:this.visibleIds, startTime: this.sceneTime.startTime, step: 60 * 1, callback: () =>{this.nextQuery.preTime = this.sceneTime.startTime} })
          // } else {
          //   // 实时模式
          //   // let now = new Date()
          //   let time = moment().utc().format('YYYY-MM-DDTHH:mm:ss') + 'Z'
          //   // let now = moment().utc().format('YYYY-MM-DDTHH:mm:ss') + 'Z'
          //   this.getMap({ sceneId: this.sceneId,checkedIds:this.visibleIds, startTime: time, step: 60 * 1, callback: () => {this.nextQuery.preTime = time}})
          // }
        }
      },
      // immediate: true
    },
  },
  mounted() {
    // 设置相机至中国区域
    viewer.cesiumViewer.camera.setView({
      destination: DT.Cesium.Cartesian3.fromDegrees(100, 40, 40000000)
    })
    // 深拷贝 store 中的场景卫星配置数据
    let satesatelliteConfig = JSON.parse(JSON.stringify(this.sceneInfo.satelliteList))
    this.satelliteConfig = satesatelliteConfig
  },
  methods: {
    /**
     * 获取地图需要渲染的，轨迹，卫星，波束
     * @author wzw
     * @date 2021-12-13
     * @param {any} option
     * @param {any} callback
     * @returns {any}
     */
    getMap: debounce(function (options) {
      options.checkedIds = options.checkedIds || []
      getRealOrbitList({ sceneId: options.sceneId, startTime: options.startTime, step: options.step }).then(res => {
        let data = res.data.data
        let lengthArr = []
        Object.keys(data).forEach(key => {
          if (data[key].length > 0) {
            lengthArr.push({
              time: data[key][data[key].length - 1].time,
              length: data[key].length,
              name: key
            })
          }

          this.updateMap(data[key], options.checkedIds)
        })
        this.nextQuery.nextTime = lengthArr.sort((a, b) => a.length - b.length)[0].time

        if (options.callback) {
          options.callback()
        } else {
          this.nextQuery.isQeury = false
        }
      })
    }, 200),
    /**
     * 更新地图上的信息
     * @author wzw
     * @date 2021-12-13
     * @param {any} data
     * @returns {any}
     */
    updateMap(data, checkedIds) {
      if (data.length === 0) return
      if (!this.isInited) {
        // 初始化渲染
        // let time = DT.Cesium.JulianDate.fromDate(new Date(data[0].time));
        // viewer.cesiumViewer.clock.currentTime = time
        // viewer.cesiumViewer.clock.shouldAnimate = true;
        this.isInited = true
        lodLayer.shouldUpdate = true
      }

      // 轨迹数据
      // let pathPositions = data.reduce((pre, next) => {
      //   return pre.concat(new DT.Cesium.Cartesian3(next.j2000X, next.j2000Y, next.j2000Z))
      // }, [])

      // 卫星实体是否已创建
      let entity = lodLayer.getEntityById(data[0].satId)
      // 卫星配置信息
      if (entity) {
        // 重绘轨迹
        // entity.redrawPolyline(pathPositions);
        // 把上次请求的数据清除掉 开始时间 结束时间
        // 更新卫星采样数据
        data.forEach(item => {
          let time = DT.Cesium.JulianDate.fromDate(new Date(item.time));
          let position = new DT.Cesium.Cartesian3(item.j2000X, item.j2000Y, item.j2000Z);
          entity.addPositionSample(time, position);
        })

      } else {
        // 创建实体
        let satelliteConfig = this.satelliteConfig.find(config => config.satId === data[0].satId)
        try {
          let satellite = new DT.Satellite({
            id: data[0].satId,
            enabled: checkedIds.length > 0 ? checkedIds.includes(data[0].satId) : false,
            reference: DT.Cesium.ReferenceFrame.INERTIAL,
            // reference: DT.Cesium.ReferenceFrame.FIXED,
            modelConfig: {
              // url: process.env.BASE_URL + 'model/sate.gltf',
              url: satelliteConfig.satBasic.style.modelFile.fileUrl,
              // url: 'data/satellite/scene.gltf',
              minimumPixelSize: 64
            },
            billboardConfig: {
              image: satelliteConfig.satBasic.style.iconFile.fileUrl
            },
            pointConfig: {
              color: DT.Cesium.Color.WHITE,
              pixelSize: 5,
            },
            labelConfig: {
              text: satelliteConfig.satBasic.satName,
              font: 'Microsoft YaHei 12px',
              pixelOffset: new DT.Cesium.Cartesian2(20, 0)
            },
            pathOptions: {
              id: 'pol-' + data[0].satId,
              pathPositions,
              material: DT.Cesium.Color.fromCssColorString(satelliteConfig.satBasic.style.orbitColor),
              width: satelliteConfig.satBasic.style.orbitWidth,
              leadTime: 60 * 60 * 24 * 365,
              trailTime: 60 * 60 * 24 * 365,
              resolution: 1200,
            },
            // alwaysShowModel: true
          })
          satellite.faceSunNodes = [
            {
              nodeName: 'TYB_1',
              faceVector: new DT.Cesium.Cartesian3(0, 1, 0)
            },
            {
              nodeName: 'TYB_2',
              faceVector: new DT.Cesium.Cartesian3(0, 1, 0)
            }
          ];
          // 添加载荷波束
          if (satelliteConfig.payloadList && satelliteConfig.payloadList.length > 0) {
            satelliteConfig.payloadList.forEach(payload => {
              // 载荷配置信息
              payload.beamList.forEach(beam => {
                // 没有波束生命周期数据不创建波束
                if (!beam.showTimeList || beam.showTimeList.length === 0) return
                // 波束配置信息
                let beamId = `${BEAM_TYPE[beam.viewType]}-${beam.beamId}`
                let beamEntity
                switch (beam.viewType) {
                  // 圆锥波束
                  case 0:
                    beamEntity = new DT.SimpleCone({
                      id: beamId, // 波束 id
                      halfAngle: DT.Cesium.Math.toRadians(beam.roundHalfAngle), // 波束半角
                      length: data[0].fixedAlt + 2000000,  // 波束高度
                      /* 
                        材质可以使用动态材质，也可使用静态颜色
                       */
                      // material: new DT.WaveMaterial({ // 动态材质
                      //   color: DT.Cesium.Color.SPRINGGREEN.withAlpha(0.8), // 波纹颜色
                      //   baseColor: DT.Cesium.Color.SPRINGGREEN.withAlpha(0.2), // 基础颜色
                      //   repeat: 30.0, // 波纹个数
                      //   thickness: 0.5, // 波纹间隔
                      //   speed: -2 // 动画速度：正数向上流动，负数向下流动
                      // }),
                      material: DT.Cesium.Color.fromCssColorString(satelliteConfig.satBasic.style.orbitColor) // 静态颜色
                    });
                    break;
                  // 矩形波束
                  case 1:
                    beamEntity = new DT.RectangularCone({
                      id: beamId, // 波束 id
                      horizontalHalfAngle: DT.Cesium.Math.toRadians(beam.horizontalHalfAngle), // 波束水平半角
                      verticalHalfAngle: DT.Cesium.Math.toRadians(beam.verticalHalfAngle), // 波束垂直半角
                      length: data[0].fixedAlt + 200000,  // 波束高度
                      /* 
                        材质可以使用动态材质，也可使用静态颜色
                       */
                      // material: new DT.WaveMaterial({ // 动态材质
                      //   color: DT.Cesium.Color.YELLOW.withAlpha(0.8), // 波纹颜色
                      //   baseColor: DT.Cesium.Color.YELLOW.withAlpha(0.2), // 基础颜色
                      //   repeat: 30.0, // 波纹个数
                      //   thickness: 0.5, // 波纹间隔
                      //   speed: -2 // 动画速度：正数向上流动，负数向下流动
                      // }, false),
                      material: DT.Cesium.Color.fromCssColorString(satelliteConfig.satBasic.style.orbitColor) // 静态颜色
                    })
                    break
                }
                // 添加波束生命周期
                beam.showTimeList.forEach(timeRange => {
                  beamEntity.availability.push(new DT.Cesium.TimeInterval({ start: DT.Cesium.JulianDate.fromIso8601(timeRange[0]), stop: DT.Cesium.JulianDate.fromIso8601(timeRange[1]) }))
                })
                beamEntity.pointing.ypr = new DT.YPR(DT.Cesium.Math.toRadians(beam.attitude.ypr[0]), DT.Cesium.Math.toRadians(beam.attitude.ypr[1]), DT.Cesium.Math.toRadians(beam.attitude.ypr[2]));
                satellite.add(beamEntity);
                // 添加条带
                if (beam.boundaryList && beam.boundaryList.length > 0) {
                  beam.boundaryList.forEach((stripe, i) => {
                    for (let i = 2; i <= stripe.boundaryCoordinate.length; i += 2) {
                      stripe.boundaryCoordinate.splice(i, 0, 500);
                      i++
                    }
                    let stripeEntity = new DT.StripeEntity({
                      id: `${beamId}-${i}-stripe`,
                      positions: DT.Cesium.Cartesian3.fromDegreesArrayHeights(stripe.boundaryCoordinate),
                      material: DT.Cesium.Color.fromCssColorString(satelliteConfig.satBasic.style.orbitColor),
                    })
                    // 添加条带生命周期
                    stripeEntity.availability.push(new DT.Cesium.TimeInterval({ start: DT.Cesium.JulianDate.fromIso8601(stripe.startTime), stop: DT.Cesium.JulianDate.fromIso8601(stripe.endTime) }))
                    satellite.add(stripeEntity);
                  })
                }
              })
            })
          }
          // 更新卫星采样数据
          data.forEach(item => {
            let time = DT.Cesium.JulianDate.fromDate(new Date(item.time));
            // let position = new DT.Cesium.Cartesian3(item.fixedX, item.fixedY, item.fixedZ);
            let position = new DT.Cesium.Cartesian3(item.j2000X, item.j2000Y, item.j2000Z);
            satellite.addPositionSample(time, position);
          })
          lodLayer.add(satellite);
        } catch (error) {
          console.log(error)
        }
      }
    },
  },
}